/**
 * Project  : Looker
 * Package  : net.freestu.looker.util
 * File     : Starter.java
 * Author   : solosky < solosky772@qq.com >
 * Date     : Aug 28, 2009
 * Modified : Aug 28, 2009
 * License  : Apache License 2.0 
 */
package net.freestu.looker.util;

import java.util.concurrent.Executors;

import net.freestu.looker.common.ConfigurationManager;
import net.freestu.looker.common.ListenerException;
import net.freestu.looker.common.Looker;
import net.freestu.looker.common.MediaListener;
import net.freestu.looker.common.NewsListener;
import net.freestu.looker.monitor.ModifyDispatcher;
import net.freestu.looker.monitor.MonitorScheduler;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger;

/**
 * 启动器
 * 初始化和启动Looker 
 */
public class Starter
{
	
	/**
	 * 日志记录器
	 */
	private static Logger logger =  Logger.getLogger(Starter.class);
	/**
	 * 初始化参数
	 * @throws ConfigurationException 
	 */
	public void loadConfiguration(String configFile) throws ConfigurationException
	{
		//加载和同步配置
		ConfigurationManager cm = ConfigurationManager.getInstance();
		cm.loadLookerConfiguration(configFile);
		//保存全局配置，方便引用
		Looker.gloalConfig = cm.getLookerConfiguration();
		//同步配置
		cm.synchronizeConfiguration();
		//线程池为自动增长和回收的线程池
		Looker.executors   = Executors.newCachedThreadPool();
	}
	
	/**
	 * 注册新闻和附件监听器
	 */
	public void registerListener()
	{
		//新闻监听器
		XMLConfiguration xmlConfig = (XMLConfiguration) Looker.gloalConfig;
		ModifyDispatcher dispatcher = ModifyDispatcher.getInstance();
		logger.info("加载新闻监听器...");
		int ln = xmlConfig.getList("listener.news.NewsListener[@class]").size();
		for(int i=0; i<ln; i++) {
			String className = xmlConfig.getString("listener.news.NewsListener("+i+")[@class]");
			try {
	            NewsListener listener = (NewsListener) Class.forName(className).newInstance();
	            listener.init(xmlConfig.configurationAt("listener.news.NewsListener("+i+")"));
	            dispatcher.registerNewsListener(listener);
	            logger.info("新闻监听器[ "+className+" ] 加载完成.");
            } catch (InstantiationException e) {
            	logger.error("加载新闻监听器时出现错误:"+e.getMessage());
            } catch (IllegalAccessException e) {
            	logger.error("加载新闻监听器时出现错误:"+e.getMessage());
            } catch (ClassNotFoundException e) {
            	logger.error("加载新闻监听器时出现错误:"+e.getMessage());
            } catch (ListenerException e) {
            	logger.error("加载新闻监听器时出现错误:"+e.getMessage());
            }
		}
		
		//加载附件监听器
		logger.info("加载附件监听器...");
		ln = xmlConfig.getList("listener.media.MediaListener[@class]").size();
		for(int i=0; i<ln; i++) {
			String className = xmlConfig.getString("listener.media.MediaListener("+i+")[@class]");
			try {
	            MediaListener listener = (MediaListener) Class.forName(className).newInstance();
	            listener.init(xmlConfig.configurationAt("listener.media.MediaListener("+i+")"));
	            dispatcher.registerMediaListener(listener);
	            logger.info("附件监听器[ "+className+" ] 加载完成.");
            } catch (InstantiationException e) {
            	logger.error("加载附件监听器时出现错误:"+e.getMessage());
            } catch (IllegalAccessException e) {
            	logger.error("加载附件监听器时出现错误:"+e.getMessage());
            } catch (ClassNotFoundException e) {
            	logger.error("加载附件监听器时出现错误:"+e.getMessage());
            } catch (ListenerException e) {
            	logger.error("加载附件监听器时出现错误:"+e.getMessage());
            }
		}
		
		logger.info("监听器加载完成.");
	}
	
	/**
	 * 启动计划器
	 */
	public void startScheduler()
	{
		logger.info("启动计划器...");
		int maxActiveListMonitor    = Looker.gloalConfig.getInt("looker.maxActiveListMonitor");
		int maxActiveContentUpdater = Looker.gloalConfig.getInt("looker.maxActiveContentUpdater");
		Looker.listMonitorScheduler = new MonitorScheduler(MonitorScheduler.MONITOR_LISTMONITOR, maxActiveListMonitor);
		Looker.contentUpdaterScheduler = new MonitorScheduler(MonitorScheduler.MONITOR_CONTENTUPDATER, maxActiveContentUpdater);
		Looker.listMonitorScheduler.init();
		Looker.contentUpdaterScheduler.init();
		Looker.listMonitorScheduler.start();
		Looker.contentUpdaterScheduler.start();
		logger.info("启动计划器完成.");
		
	}
	
	/**
	 * 开始运行
	 * @throws ConfigurationException 
	 */
	public void start(String configFile) throws ConfigurationException
	{
		loadConfiguration(configFile);
		registerListener();
		startScheduler();
	}
	
	/**
	 * 关闭Looker
	 */
	public void stop()
	{
		//中断计划器线程
		Looker.listMonitorScheduler.stop();
		Looker.contentUpdaterScheduler.stop();
		//关闭线程池
		Looker.executors.shutdown();
	}

}
